import { Page, View, Document,Text } from "@react-pdf/renderer";
import { styles, spacing } from "components/Resume/ResumePDF/styles";
import { ResumePDFProfile } from "components/Resume/ResumePDF/ResumePDFProfile";
import { ResumePDFWorkExperience } from "components/Resume/ResumePDF/ResumePDFWorkExperience";
import { ResumePDFEducation } from "components/Resume/ResumePDF/ResumePDFEducation";
import { ResumePDFProject } from "components/Resume/ResumePDF/ResumePDFProject";
import { ResumePDFSkills } from "components/Resume/ResumePDF/ResumePDFSkills";
import { ResumePDFCustom } from "components/Resume/ResumePDF/ResumePDFCustom";
import {DEFAULT_FONT_COLOR, ShowFormPoster} from "lib/redux/settingsSlice";
import type { Settings, ShowForm } from "lib/redux/settingsSlice";
import type { Resume } from "lib/redux/types";
import { SuppressResumePDFErrorMessage } from "components/Resume/ResumePDF/common/SuppressResumePDFErrorMessage";
import { Image } from "@react-pdf/renderer";
import { ResumePDFImage } from "./common/ResumePDFImage";
import { useState, useEffect } from 'react';
import { StyleSheet } from '@react-pdf/renderer';
import {ResumePDFAbstract} from "./ResumePDFAbstract";
import {ResumePDFMethod} from "./ResumePDFMethod";
import {ResumePDFExperiment} from "./ResumePDFExperiment";
import {ResumePDFIntroduction} from "./ResumePDFIntroduction";
import {ResumePDFConclusion} from "./ResumePDFConclusion";

/**
 * Note: ResumePDF is supposed to be rendered inside PDFViewer. However,
 * PDFViewer is rendered too slow and has noticeable delay as you enter
 * the resume form, so we render it without PDFViewer to make it render
 * instantly. There are 2 drawbacks with this approach:
 * 1. Not everything works out of box if not rendered inside PDFViewer,
 *    e.g. svg doesn't work, so it takes in a isPDF flag that maps react
 *    pdf element to the correct dom element.
 * 2. It throws a lot of errors in console log, e.g. "<VIEW /> is using incorrect
 *    casing. Use PascalCase for React components, or lowercase for HTML elements."
 *    in development, causing a lot of noises. We can possibly workaround this by
 *    mapping every react pdf element to a dom element, but for now, we simply
 *    suppress these messages in <SuppressResumePDFErrorMessage />.
 *    https://github.com/diegomura/react-pdf/issues/239#issuecomment-487255027
 */


export const ResumePDF = ({
                              resume,
                              settings,
                              isPDF = false,
                          }: {
    resume: Resume;
    settings: Settings;
    isPDF?: boolean;
}) => {
    // 新增状态用于存储txt文件内容
    const [rawHTML, setRawHTML] = useState<string>("");

    // 新增读取txt文件的effect
    useEffect(() => {
        // 假设你的txt文件位于public目录下
        fetch('/sample1.txt')
            .then(response => {
                console.log('Response status:', response.status); // ✅ 检查状态码
                return response.text();
            })
            .then(text => setRawHTML(text))
            .catch(error => console.error('读取文件失败:', error));
    }, []);

    //将 HTML 转换为树形结构
    const parser = new DOMParser();
    const doc = parser.parseFromString(rawHTML, "text/html");
    //忽略嵌套结构，只保留直接子元素
    // 明确指定children集合的类型为HTMLCollectionOf<Element>
    const children = doc.body.children as HTMLCollectionOf<Element>;
    // 使用类型断言+泛型参数双重保障
    const flattenElements = Array.from<Element>(children)
        .filter(el => el.tagName.toLowerCase() === 'div'); // 注意转为小写比较
    //通过 class 名识别元素类型
    const typeMap = {
        'text': 'text',
        'image': 'image',
        'abstract': 'section',
        'method': 'section',
        'introduction':'section',
        'experiment':'section',
        'conclusion':'section',
    };
    //样式提取与标准化
    const extractStyles = (element) => {
        const rawStyle = element.getAttribute('style') || '';

        // 样式解析（支持缩写属性）
        const styleObj = rawStyle.split(';').reduce((acc, pair) => {
            const [key, value] = pair.split(':').map(s => s.trim());
            if (key && value) {
                acc[key] = value.endsWith('px')
                    ? parseInt(value.replace('px', ''), 10)
                    : value;
            }
            return acc;
        }, {});

        // 单位转换规则
        const convertRules = {
            left: v => v * 0.75,  // px -> pt (1px=0.75pt)
            top: v => v * 0.75,
            width: v => v * 0.75,
            height: v => v * 0.75
        };

        return Object.entries(styleObj).reduce((acc, [key, value]) => {
            acc[key] = convertRules[key] ? convertRules[key](value) : value;
            return acc;
        }, {});
    };

    const convertBodyStyleToReactPDF = (html: string): React.CSSProperties => {
        const doc = new DOMParser().parseFromString(rawHTML, "text/html");
        const bodyElement = doc.body;
        const rawStyle = bodyElement.getAttribute('style') || '';

        return rawStyle.split(';').reduce((acc, pair) => {
            const [key, value] = pair.split(':').map(s => s.trim());
            if (!key || !value) return acc;

            // 单位转换逻辑
            const parseValue = (val: string): string | number => {
                if (val.endsWith('mm')) return parseFloat(val) * 2.83465; // mm → pt
                if (val.endsWith('px')) return parseFloat(val) * 0.75;    // px → pt
                return /^\d/.test(val) ? parseFloat(val) : val;
            };

            return {
                ...acc,
                [key]: parseValue(value)
            };
        }, {} as React.CSSProperties);
    };

    const convertHTMLToMetadata = (rawHTML: string) => {
        const doc = new DOMParser().parseFromString(rawHTML, "text/html");
        console.log("解析后的 DOM:", doc.documentElement.outerHTML);
        const bodyElement = doc.body;
        const rawStyle = bodyElement.getAttribute('style') || '';
        console.log("body:", rawStyle);

        const sections: Array<{ type: string; elements: any[] }> = [];

        // 显式定义目标类名数组
        const targetClasses = ['abstract', 'method', 'introduction', 'experiment', 'conclusion'] as const;

        targetClasses.forEach(className => {
            // 使用类型断言确保元素存在
            const sectionDiv = doc.querySelector(`.${className}`) as HTMLElement | null;
            if (!sectionDiv) return;

            // 处理 HTMLCollection 的类型问题
            const children = Array.from(sectionDiv.children as HTMLCollectionOf<Element>);

            const elements = children.map(child => {
                // 添加类型保护
                const classNames = (child as HTMLElement).className.split(' ');
                const type = classNames.includes('text') ? 'text' :
                    classNames.includes('image') ? 'image' :
                        'unknown';

                return {
                    elementType: type,
                    content: type === 'text' ?
                        (child as HTMLElement).textContent?.trim() || '' :
                        (child.querySelector('img') as HTMLImageElement | null)?.src || '',
                    styles: extractStyles(child as HTMLElement)
                };
            });

            sections.push({
                type: className,
                elements
            });
        });

        return { sections };
    };

    const metaData = convertHTMLToMetadata(rawHTML);

    // 核心组件映射器
    const ElementRenderer = ({ element }: { element: any }) => {
        if (element.elementType === 'text') {
            return (
                <Text
                    style={{
                        position: 'absolute',
                        ...element.styles,
                        fontSize: element.styles.fontSize * 0.75, // 二次转换确保pt单位
                        left: `${element.styles.left}pt`,
                        top: `${element.styles.top}pt`
                    }}
                >
                    {element.content}
                </Text>
            );
        }

        if (element.elementType === 'image') {
            return (
                <Image
                    src={element.content}
                    style={{
                        position: 'absolute',
                        ...element.styles,
                        width: `${element.styles.width}pt`,
                        height: `${element.styles.height}pt`
                    }}
                />
            );
        }

        return null;
    };

    // 布局修正函数（处理用户遇到的Method章节重叠问题）
    const adjustElementPositions = (elements: any[]) => {
        let currentTop = 0;
        return elements.map((el, index) => {
            // 首个元素保持原位置，后续元素垂直排列
            const adjustedEl = index === 0 ? el : {
                ...el,
                styles: {
                    ...el.styles,
                    top: currentTop + 20 // 添加20pt间距
                }
            };
            currentTop = adjustedEl.styles.top + adjustedEl.styles.height;
            return adjustedEl;
        });
    };

    // 在章节容器中使用
    const SectionContainer = ({ section }: { section: any }) => {
        const adjustedElements = adjustElementPositions(section.elements);

        return (
            <View style={styles.section}>
                <Text style={styles.sectionTitle}>{section.type}</Text>
                {adjustedElements.map((el, idx) => (
                    <ElementRenderer key={idx} element={el} />
                ))}
            </View>
        );
    };

    // 最终PDF文档结构
    const GeneratedPoster = () => (
        <Document>
            <Page size="A4" style={styles.page}>
                {metaData.sections.map((section, index) => (
                    <SectionContainer key={index} section={section} />
                ))}
                {/* 添加页脚 */}
                <Text style={styles.footer}>
                    Generated by PosterGenius - {new Date().toLocaleDateString()}
                </Text>
            </Page>
        </Document>
    );

    // 第一步：定义 React-PDF 专用样式类型
    type ReactPdfStyle = Parameters<typeof Page>[0]['style'];

// 第二步：增强类型安全转换函数
    const convertToReactPdfStyle = (
        reactStyles: React.CSSProperties
    ): ReactPdfStyle => {
        // 过滤不支持的属性
        const allowedProperties = new Set(['margin', 'padding', 'width', 'height' /* 其他支持的属性 */]);

        return Object.entries(reactStyles).reduce((acc, [key, value]) => {
            // 处理数字值转换
            if (typeof value === 'number') {
                return { ...acc, [key]: value };
            }

            // 处理带单位字符串的转换
            if (typeof value === 'string') {
                const numericValue = parseFloat(value);
                if (!isNaN(numericValue)) {
                    return { ...acc, [key]: numericValue };
                }
            }

            // 保留有效字符串值（如颜色值）
            if (typeof value === 'string' && /^#|rgb|transparent$/.test(value)) {
                return { ...acc, [key]: value };
            }

            return acc;
        }, {});
    };

    /******************************************************
    * 分割线
    *******************************************************/

    const bodyStyles = convertBodyStyleToReactPDF(rawHTML);
    const pdfStyles = convertToReactPdfStyle(bodyStyles);
    // 新增状态管理 process.env.IMAGE_PATH
    const [bgImageUrl, setBgImageUrl] = useState<string>(
        settings.background.url || "/images/default-bg.jpg"
    );
    const background = settings.background;
    const BG_IMAGE_PATH = background.url || "/images/default-bg.jpg";
    //console.log("BG_IMAGE_PATH:", BG_IMAGE_PATH);

    const { profile, workExperiences, educations, projects, skills, custom } =
        resume;
    const { name } = profile;
    const {
        fontFamily,
        fontSize,
        documentSize,
        formToHeading,
        formToHeadingPoster,
        formToShow,
        formToShowPoster,
        formsOrder,
        formsOrderPoster,
        showBulletPoints
    } = settings;
    const themeColor = settings.themeColor || DEFAULT_FONT_COLOR;

    const showFormsOrder = formsOrder.filter((form) => formToShow[form]);
    //poster的五个部分
    const showFormsOrderPoster = formsOrderPoster.filter((form) => formToShowPoster[form])

    const abstractSection = metaData.sections.find(
        section => section.type === 'abstract'
    );
    console.log("abs",abstractSection)
    const methodSection = metaData.sections.find(
        section => section.type === 'method'
    );
    const introductionSection = metaData.sections.find(
        section => section.type === 'introduction'
    );
    const experimentSection = metaData.sections.find(
        section => section.type === 'experiment'
    );
    const conclusionSection = metaData.sections.find(
        section => section.type === 'conclusion'
    );

    const formTypeToPosterComponent: { [type in ShowFormPoster]: () => JSX.Element } = {
        abstract: () => (
            <ResumePDFAbstract
                heading={formToHeadingPoster["abstract"]}
                abstract={abstractSection}
                themeColor={themeColor}
            />
        ),
        method: () => (
            <ResumePDFMethod
                heading={formToHeadingPoster["method"]}
                method={methodSection}
                themeColor={themeColor}
            />
        ),
        introduction: () => (
            <ResumePDFIntroduction
                heading={formToHeadingPoster["introduction"]}
                introduction={introductionSection}
                themeColor={themeColor}
            />
        ),
        experiment: () => (
            <ResumePDFExperiment
                heading={formToHeadingPoster["experiment"]}
                experiment={experimentSection}
                themeColor={themeColor}
            />
        ),
        conclusion: () => (
            <ResumePDFConclusion
                heading={formToHeadingPoster["conclusion"]}
                conclusion={conclusionSection}
                themeColor={themeColor}
            />
        ),
    };

    return (
        <>
            <Document title={`${name} Resume`} author={name} producer={"OpenResume"}>
                <Page
                    size={documentSize === "A4" ? "A4" : "LETTER"}
                    style={pdfStyles}
                >
                    {/* 新增固定背景层 */}
                    <ResumePDFImage
                        isPDF={isPDF}
                        src={BG_IMAGE_PATH} // 使用环境变量
                        style={{
                            position: 'absolute',
                            top: 0,
                            left: 0,
                            width: '100%',
                            height: '100%',
                            opacity: background.opacity,
                            zIndex: 0,
                            objectFit: 'cover'
                        }}
                    />
                    {Boolean(settings.themeColor) && (
                        <View
                            style={{
                                width: spacing["full"],
                                height: spacing[3.5],
                                backgroundColor: themeColor,
                            }}
                        />
                    )}
                    <View
                        style={{
                            ...styles.flexCol,
                            padding: `${spacing[0]} ${spacing[20]}`,
                        }}
                    >
                        <ResumePDFProfile
                            profile={profile}
                            themeColor={themeColor}
                            isPDF={isPDF}
                        />
                        {/*{showFormsOrder.map((form) => {
                            const Component = formTypeToComponent[form];
                            return <Component key={form} />;
                        })}*/}
                        {showFormsOrderPoster.map((form) => {
                            const Component = formTypeToPosterComponent[form];
                            return <Component key={form} />;
                        })}
                    </View>
                </Page>
            </Document>
            <SuppressResumePDFErrorMessage />
        </>
    );
};
